package com.lujianfei.imagesearch.ui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JDesktopPane;
import javax.swing.JPanel;

import com.lujianfei.imagesearch.Constants;
import com.lujianfei.imagesearch.base.BaseChildWindow;
import com.lujianfei.imagesearch.base.BaseChildWindow.OnCloseListener;
import com.lujianfei.imagesearch.base.BaseMenuWindow;
import com.lujianfei.imagesearch.contract.MainContract;
import com.lujianfei.imagesearch.presenter.MainPresenter;
import com.lujianfei.imagesearch.ui.subui.CanvasWindow;
import com.lujianfei.imagesearch.utils.MnistReader.MnistInfo;
import com.lujianfei.lib.dialog.MessageBox;
import com.lujianfei.lib.sdautolayout.impl.SDAutoLayout;
import com.lujianfei.lib.window.BaseInternalWindow;

public class MainWindow extends BaseMenuWindow implements MainContract.View {

	MainContract.Presenter presenter;

	JPanel jpanel = new JPanel();
	
	List<BaseInternalWindow> childFrames = new ArrayList<>();
	
	JDesktopPane desktopPane;

	public MainWindow() {
		super();
		setTitle("图像处理研究");
//		add(jpanel);
		jpanel.setBackground(Color.DARK_GRAY);
		SDAutoLayout.forComponent(jpanel).widthIs(getWidth()).heightIs(getHeight());
		presenter = new MainPresenter(this);
		
		desktopPane = new JDesktopPane();
		getContentPane().add(desktopPane, BorderLayout.CENTER);
		
		desktopPane.add(jpanel);
		desktopPane.setLayer(jpanel, -1);
	}

	@Override
	protected List<MenuBean> getMenuBean() {
		List<MenuBean> menus = new ArrayList<>();
		List<MenuBean> menusFileChild = new ArrayList<>();
		menus.add(new MenuBean.Builder().setName("文件(F)").setMnemonic('f').setChilds(menusFileChild).create());
		menusFileChild.add(new MenuBean.Builder().setName("打开(O)").setMnemonic('o').setActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				presenter.openFile(Constants.SUBFrameType.IMAGE);
			}
		}).addSeparator().create());
		menusFileChild.add(new MenuBean.Builder().setName("导入Mnist图像(M)").setMnemonic('o').setActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				presenter.openFile(Constants.SUBFrameType.MNIST_DATA);
			}
		}).addSeparator().create());
		menusFileChild.add(new MenuBean.Builder().setName("导入MnistLabel(M)").setMnemonic('o').setActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				presenter.openFile(Constants.SUBFrameType.MNIST_LABEL);
			}
		}).addSeparator().create());
		menusFileChild.add(new MenuBean.Builder().setName("退出(X)").setMnemonic('x').setActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				// TODO Auto-generated method stub
				exit();
			}
		}).create());
		List<MenuBean> menusOperationChild = new ArrayList<>();
		menus.add(new MenuBean.Builder().setName("处理(P)").setMnemonic('p').setChilds(menusOperationChild).create());
		menusOperationChild.add(new MenuBean.Builder().setName("灰度(最大值法)").setActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				if(null!=getCurrentCanvas()) {
					addGray(Constants.GRAY_MODE.MAX);
				} else {
					showTips();
				}
			}
			
		}).create());
		menusOperationChild.add(new MenuBean.Builder().setName("灰度(最小值法)").setActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				if(null!=getCurrentCanvas()) {
					addGray(Constants.GRAY_MODE.MIN);
				} else {
					showTips();
				}
			}
		}).create());
		menusOperationChild.add(new MenuBean.Builder().setName("灰度(均值法)").setActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				if(null!=getCurrentCanvas()) {
					addGray(Constants.GRAY_MODE.AVE);
				} else {
					showTips();
				}
			}
		}).create());
		menusOperationChild.add(new MenuBean.Builder().setName("灰度(加权法)").setActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				if(null!=getCurrentCanvas()) {
					addGray(Constants.GRAY_MODE.WEIGHT);
				} else {
					showTips();
				}
			}
		}).addSeparator().create());
		menusOperationChild.add(new MenuBean.Builder().setName("添加噪点(椒盐噪声)").setActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				if(null!=getCurrentCanvas()) {
					addNoise(Constants.NOISE_MODE.PEPPER_SALT_NOISE);
				} else {
					showTips();
				}
			}
		}).create());
		menusOperationChild.add(new MenuBean.Builder().setName("添加噪点(胡椒噪声)").setActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				if(null!=getCurrentCanvas()) {
					addNoise(Constants.NOISE_MODE.PEPPER_NOISE);
				} else {
					showTips();
				}
			}
		}).create());
		menusOperationChild.add(new MenuBean.Builder().setName("添加噪点(盐噪声)").setActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				if(null!=getCurrentCanvas()) {
					addNoise(Constants.NOISE_MODE.SALT_NOISE);
				} else {
					showTips();
				}
			}
		}).addSeparator().create());
		menusOperationChild.add(new MenuBean.Builder().setName("去噪(均值滤波)").setActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				// TODO Auto-generated method stub
				if(null!=getCurrentCanvas()) {
					removeNoise(Constants.REMOVE_NOISE_MODE.MEAN_FILTER);
				} else {
					showTips();
				}
			}
		}).create());
		menusOperationChild.add(new MenuBean.Builder().setName("去噪(中值滤波)").setActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				// TODO Auto-generated method stub
				if(null!=getCurrentCanvas()) {
					removeNoise(Constants.REMOVE_NOISE_MODE.MEDIUM_FILTER);
				} else {
					showTips();
				}
			}
		}).create());
		menusOperationChild.add(new MenuBean.Builder().setName("去噪(最大最小值滤波)").setActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				// TODO Auto-generated method stub
				if(null!=getCurrentCanvas()) {
					removeNoise(Constants.REMOVE_NOISE_MODE.MAXMIN_FILTER);
				} else {
					showTips();
				}
			}
		}).addSeparator().create());
		menusOperationChild.add(new MenuBean.Builder().setName("还原").setActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				// TODO Auto-generated method stub
				if(null!=getCurrentCanvas()) {
					restore();
				} else {
					showTips();
				}
			}
		}).create());
		return menus;
	}
	
	private void addGray(int type) {
		BaseInternalWindow currentCanvas = getCurrentCanvas();
		if (currentCanvas instanceof CanvasWindow) {
			((CanvasWindow)currentCanvas).getPresenter().addGray(Constants.GRAY_MODE.MAX);
		}
	}
	private void addNoise(int type) {
		BaseInternalWindow currentCanvas = getCurrentCanvas();
		if (currentCanvas instanceof CanvasWindow) {
			((CanvasWindow)currentCanvas).getPresenter().addNoise(type);
		}
	}
	private void removeNoise(int type) {
		BaseInternalWindow currentCanvas = getCurrentCanvas();
		if (currentCanvas instanceof CanvasWindow) {
			((CanvasWindow)currentCanvas).getPresenter().removeNoise(type);
		}
	}
	
	private void restore() {
		BaseInternalWindow currentCanvas = getCurrentCanvas();
		if (currentCanvas instanceof CanvasWindow) {
			((CanvasWindow)currentCanvas).getPresenter().restore();
		}
	}
	
	private void showTips() {
		MessageBox.show(MainWindow.this, "请先打开图片文件");
	}
	

	@Override
	public Component getContext() {
		// TODO Auto-generated method stub
		return this;
	}

	@Override
	public void setImage(String absolutePath,int type) {
		// TODO Auto-generated method stub
		MnistInfo info = new MnistInfo();
		BaseChildWindow childFrame = ChildWindowFactory.getChildWindow(absolutePath,type,info);
		if (!info.success) {
			MessageBox.show(this,info.message);
			return;
		}
		desktopPane.add(childFrame);
		try {
			childFrame.setSelected(true);
		} catch (Exception e) {
			e.printStackTrace();
		}
		childFrame.setOnCloseListener(new OnCloseListener() {
			
			@Override
			public void onClose(Object frame) {
				// TODO Auto-generated method stub
				childFrames.remove(frame);
			}
		});
		childFrames.add(childFrame);
	}

	
	@Override
	public BufferedImage getImage() {
		BaseInternalWindow currentCanvas = getCurrentCanvas();
		if (currentCanvas instanceof CanvasWindow) {
			return ((CanvasWindow)currentCanvas).getImage();
		}
		return null;
	}

	@Override
	public void updateImage() {
		// TODO Auto-generated method stub
		BaseInternalWindow currentCanvas = getCurrentCanvas();
		if (currentCanvas instanceof CanvasWindow) {
			((CanvasWindow)currentCanvas).updateImage();
		}
	}

	private BaseInternalWindow getCurrentCanvas() {
		
		for (BaseInternalWindow canvasWindow : childFrames) {
			if (canvasWindow.isSelected()) {
				return canvasWindow;
			}
		}
		
		if (1 == childFrames.size()) {
			return childFrames.get(0);
		}
		return null;
	}
	
	
	@Override
	protected void onDestroy() {
		super.onDestroy();
		for (BaseInternalWindow canvasWindow : childFrames) {
			canvasWindow.dispose();
		}
		childFrames.clear();
	}

}
